bitkeeper revision 1.1159.258.58 (4238008ex_KSQqR2a5fd8soijqba4g)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 16 Mar 2005 09:46:54 +0000 (09:46 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 16 Mar 2005 09:46:54 +0000 (09:46 +0000)
If a Linux guest is allocated more memory than it can use (due to
highmem constraints) it will now give that RAM back to Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c

index 46507fbd93c44f04368386e910d8f0c8cce36971..50fc7c1b133c83cc68d9cca15babbb2d6309b588 100644 (file)
@@ -377,15 +377,31 @@ void __init setup_arch(char **cmdline_p)
 
     paging_init();
 
-    /* Make sure we have a large enough P->M table. */
-    if ( max_pfn > xen_start_info.nr_pages )
+    /* Make sure we have a correctly sized P->M table. */
+    if ( max_pfn != xen_start_info.nr_pages )
     {
         phys_to_machine_mapping = alloc_bootmem_low_pages(
             max_pfn * sizeof(unsigned long));
-        memset(phys_to_machine_mapping, ~0, max_pfn * sizeof(unsigned long));
-        memcpy(phys_to_machine_mapping,
-               (unsigned long *)xen_start_info.mfn_list,
-               xen_start_info.nr_pages * sizeof(unsigned long));
+        if ( max_pfn > xen_start_info.nr_pages )
+        {
+            memset(phys_to_machine_mapping, ~0,
+                   max_pfn * sizeof(unsigned long));
+            memcpy(phys_to_machine_mapping,
+                   (unsigned long *)xen_start_info.mfn_list,
+                   xen_start_info.nr_pages * sizeof(unsigned long));
+        }
+        else
+        {
+            memcpy(phys_to_machine_mapping,
+                   (unsigned long *)xen_start_info.mfn_list,
+                   max_pfn * sizeof(unsigned long));
+            if (HYPERVISOR_dom_mem_op(
+                MEMOP_decrease_reservation,
+                (unsigned long *)xen_start_info.mfn_list + max_pfn,
+                xen_start_info.nr_pages - max_pfn, 0) !=
+                (xen_start_info.nr_pages - max_pfn))
+                BUG();
+        }
         free_bootmem(__pa(xen_start_info.mfn_list), 
                      PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
                                      sizeof(unsigned long))));
index 9b892b04ba264f5185a37dbf01043a9ad01a4db4..8551fad5a72dd92d26d3d596e98925d9848274d1 100644 (file)
@@ -1491,15 +1491,26 @@ void __init setup_arch(char **cmdline_p)
 #endif
        paging_init();
 
-       /* Make sure we have a large enough P->M table. */
-       if (max_pfn > xen_start_info.nr_pages) {
+       /* Make sure we have a correctly sized P->M table. */
+       if (max_pfn != xen_start_info.nr_pages) {
                phys_to_machine_mapping = alloc_bootmem_low_pages(
                        max_pfn * sizeof(unsigned long));
-               memset(phys_to_machine_mapping, ~0,
-                       max_pfn * sizeof(unsigned long));
-               memcpy(phys_to_machine_mapping,
-                       (unsigned long *)xen_start_info.mfn_list,
-                       xen_start_info.nr_pages * sizeof(unsigned long));
+               if (max_pfn > xen_start_info.nr_pages) {
+                       memset(phys_to_machine_mapping, ~0,
+                               max_pfn * sizeof(unsigned long));
+                       memcpy(phys_to_machine_mapping,
+                               (unsigned long *)xen_start_info.mfn_list,
+                               xen_start_info.nr_pages * sizeof(unsigned long));
+               } else {
+                       memcpy(phys_to_machine_mapping,
+                               (unsigned long *)xen_start_info.mfn_list,
+                               max_pfn * sizeof(unsigned long));
+                       if (HYPERVISOR_dom_mem_op(
+                               MEMOP_decrease_reservation,
+                               (unsigned long *)xen_start_info.mfn_list + max_pfn,
+                               xen_start_info.nr_pages - max_pfn, 0) !=
+                           (xen_start_info.nr_pages - max_pfn)) BUG();
+               }
                free_bootmem(
                        __pa(xen_start_info.mfn_list), 
                        PFN_PHYS(PFN_UP(xen_start_info.nr_pages *